import { any } from "../logic"
import { TinySDF } from "./TinySDF";
class Atlas {
    constructor(opts = {}) {
        this.text = any(opts.text, "");
        this.fontSize = any(opts.fontSize, this.fontSize, 48);
        this.buffer=any(opts.buffer,Math.ceil(this.fontSize / 8));
        this.cutoff = any(opts.cutoff, 0.25);
        this.fontFamily = any(opts.fontFamily, 'sans-serif');
        this.fontWeight = any(opts.fontWeight, 500);
        this.fontStyle = any(opts.fontStyle, 'normal');
    }
    addText(v) {
        for (let t of v) {
            if (!this.text.includes(t)) {
                this.text += t;
            }
        }
    }
    clearText() {
        this.text = "";
    }
    generate() {
        let sdfs={};
        let opts={
            fontSize: this.fontSize,
            buffer: this.buffer,
            radius: Math.ceil(this.fontSize / 3),
            fontWeight: this.fontWeight,
            fontStyle: this.fontStyle,
            fontFamily: this.fontFamily
        }
        let size=opts.fontSize+2*opts.buffer;
        if(size>8192){
            throw new Error("图集大小过大建议减小字体大小或减少字体");
        }
        let csize=Math.pow(2,Math.ceil(Math.log2(Math.ceil(Math.sqrt(this.text.length)*size))));
        if(!this.canvas){
            this.canvas=this.createCanvas(csize);
        }else{
            this.canvas.width=this.canvas.height=csize;
        }
        const sdf = new TinySDF(opts);
        this.canvas.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        const codePoints = this.text[Symbol.iterator]();
        let codePoint = codePoints.next();
        for (let y = 0; y + size <= this.canvas.height && !codePoint.done; y += size) {
            for (let x = 0; x + size <= this.canvas.width && !codePoint.done; x += size) {
                const {data, width, height,glyphTop} = sdf.draw(codePoint.value);
                this.canvas.ctx.putImageData(this.makeRGBAImageData(data, width, height), x, y-glyphTop);
                sdfs[codePoint.value] = {x,y,w:width};
                codePoint = codePoints.next();
            }
        }
        let json={width:csize,height:csize,fontSize:size,texture:sdfs}
        let  image = new Image();
        let  dataURL = this.canvas.toDataURL("image/png");
        image.src = dataURL;
        return {sdfs:json,"image":dataURL}
    }
    makeRGBAImageData(alphaChannel, width, height) {
        const imageData = this.canvas.ctx.createImageData(width, height);
        for (let i = 0; i < alphaChannel.length; i++) {
            imageData.data[4 * i + 0] = alphaChannel[i];
            imageData.data[4 * i + 1] = alphaChannel[i];
            imageData.data[4 * i + 2] = alphaChannel[i];
            imageData.data[4 * i + 3] = 255;
        }
        return imageData;
    }
    createCanvas(size) {
        const canvas = document.createElement('canvas');
        canvas.width = canvas.height = size;
        canvas.ctx = canvas.getContext('2d', {willReadFrequently: true});
        return canvas;
    }

}
export { Atlas }